﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;

namespace DeepTalkDBSerice
{
    /// <summary>
    /// Utilitiy class to centralize all the  management of the talk state.
    /// To first order this is pretty simple, but who knows what will happen
    /// as this thing grows!
    /// </summary>
    class ManageTalkState
    {
        /// <summary>
        /// Sets the state to some number... Ignore if the current state is one of the listed.
        /// </summary>
        /// <param name="id"></param>
        /// <param name="newState"></param>
        /// <param name="betterStates">List of states that if the talk is in we don't reset to.</param>
        private static void SetTalkState(int id, Conference.ConferenceState newState, Conference.ConferenceState[] betterStates)
        {
            using (ConferenceModelContainer cont = DBUtilities.GetConferenceContainer())
            {
                {
                    ///
                    /// Get the meeting. The ToArray below is there to make sure the cursor gets closed. If it
                    /// isn't, then it is impossible to reliably call saveChanges.
                    /// 

                    var theMeeting = from m in cont.ConferenceSet
                                     where m.Id == id
                                     select m;
                    Conference[] cs = theMeeting.ToArray();

                    if (cs.Length == 0)
                    {
                        throw new ArgumentException("Unable to find talk with ID " + id.ToString());
                    }

                    ///
                    /// If the conf is already in one of the "better" states, then ignore this.
                    /// This is because there are some DB ordering issues that go on with multi-threaded
                    /// code sometimes.
                    /// 

                    if (betterStates.Contains(cs[0].CurrentState))
                    {
                        Trace.WriteLine("Talk " + id + " is in a better state - not going to update it!");
                        return;
                    }

                    ///
                    /// Update the state.
                    /// 

                    Trace.WriteLine("Updating talk ID " + id + " to new state " + newState.ToString() + " with from old state " + cs[0].CurrentState.ToString());
                    cs[0].CurrentState = newState;
                }
                int result = cont.SaveChanges();
            }
        }

        /// <summary>
        /// Set the state no matter what...
        /// </summary>
        /// <param name="id"></param>
        /// <param name="newState"></param>
        private static void SetTalkState(int id, Conference.ConferenceState newState)
        {
            SetTalkState(id, newState, new Conference.ConferenceState[0]);
        }

        /// <summary>
        /// Set the talk state to be rendered. Don't do this is the talk is in the rendered state already.
        /// </summary>
        /// <param name="id"></param>
        public static void SetStateRendering (int id)
        {
            SetTalkState(id, Conference.ConferenceState.Rendering, new DeepTalkDBSerice.Conference.ConferenceState[] { Conference.ConferenceState.Rendered} );
            Trace.WriteLine("Setting talk " + id.ToString() + " to be rendering state");
        }

        /// <summary>
        /// Set the talk state to be rendered.
        /// </summary>
        /// <param name="id"></param>
        public static void SetStateRendered(int id)
        {
            SetTalkState(id, Conference.ConferenceState.Rendered);
            Trace.WriteLine("Setting talk " + id.ToString() + " to be rendered state");
        }

        /// <summary>
        /// Set the talk state to be rendered.
        /// </summary>
        /// <param name="id"></param>
        public static void SetStateUnrendered(int id)
        {
            SetTalkState(id, Conference.ConferenceState.Unrendered);
            Trace.WriteLine("Setting talk " + id.ToString() + " to unrendered state");
        }
    }
}
